/**
 * Magic ComboBox v2.1.4
 * Author: Mac_J@boarsoft.com
 * Need: core.js
 * 
 * 1、支持数组参数
 * 2、增加disable方法
 * 3、增加val(?)方法
 */
mac.combo = function(self, cfg) {
	self.config = cfg = $.extend({
		height : 24,
		maxkLen : 20,
		comma : ',',
		name : self.prop('name')
	}, cfg);
	self.selected = cfg.selected || [];
	var cols = cfg.cols;
	var cw = cfg.width, ch = cfg.height;
	var hd = $('<div class="head"><div>').width(cw).height(ch);
	var tf = $('<input type="text" />').height(ch).width('100%');
	var tw = $('<div class="left"></div>').css('margin-right', ch).height(ch + 2);
	tf.prop({
		name : cfg.name,
		maxLength : cfg.maxLen
	}).click(function(){
		return false;
	}).keydown(function(e) {
		var k = e.keyCode, op = self.isOpen
			, rs = bd.find('.tr'), v = tf.val();
		if (e.ctrlKey && k == 'a') {
			return true;
		}
		switch (k) {
		case 9: //TAB
		case 27:// ESC
			self.close();
			tf.focus();
			break;
		case 38: // UP
		case 40: // DOWN
			var d = (k == 40), h = rs.filter('.hover')
				, s = rs.filter('.selected'), x;
			if (!op && d) {
				self.key = v;
				self.open();
			}
			if (h.length) {
				h = h.removeClass('hover').first();
				x = d? h.next():h.prev();
			}
			if (!x || !x.length) {
				x = d? rs.first() : rs.last();
			}
			if (x.length) {
				x.addClass('hover');
			}
			return false;
		case 13:// RETURN
			var h = rs.filter('.hover');
			if (op) {
				if (h.length) {
					h.click();
					h.removeClass('hover');
				}
			} else {
				self.open();
			}
			return false;
		}
		return true;
	});
	var btn = self.btn = $('<div class="btn"></div>');
	var ico = $('<span class="icon icon-triangle-1-s"></span>');
	ico.css('margin', Math.floor(ch / 2 - 8)).appendTo(btn);
	btn.height(ch).width(ch).css('margin-top', -ch - 2);
	tw.append(tf);
	hd.append(tw).append(btn);
	var bd = $('<div class="body"></div>');
	if (cfg.boxHeight)
		bd.height(cfg.boxHeight);
	if (cfg.boxEl) {
		bd.append(cfg.boxEl);
		bd.addClass('box');
	}
	bd.click(function(e) {
		e.stopPropagation();
		return false;
	});
	btn.click(function() {
		if (self.hasClass('disabled')) {
			return;
		}
		if (self.isOpen) {
			self.close();
		} else {
			self.open();
		}
		return false;
	});
	self.append(hd).append(bd);
	if (cfg.readOnly) {
		tf.attr('readonly', 'readonly');
		tf.click(function() {
			btn.click();
			return false;
		});
	}
	self.close = function() {
		self.isOpen = false;
		bd.children('.tr').removeClass('hover');
		bd.hide();
		if (cfg.onClose) {
			cfg.onClose(self);
		}
	}
	tf.change(function() {
		if (!tf.val()) {
			self.select([]);
		}
	});
	self.open = function() {
		self.isOpen = true;
		var w = cfg.boxWidth || self.width()
			, p = self.position(), bt = cfg.boxTop, bl = cfg.boxLeft;
		bt = (bt || bt == 0) ? bt : (cfg.height + 2);
		bl = (bl || bl == 0) ? bl : 0;
		bd.css({
			top : p.top + bt,
			left : p.left + bl
		});
		bd.width(Math.max(w, cfg.boxMinWidth || w)).show();
		if (cfg.onOpen) {
			cfg.onOpen(self);
		}
		$(document).one('click', self.close);
	}
	self.enable = function(){
		self.removeClass('disabled');
	}
	self.disable = function(){
		self.addClass('disabled');
	}
	self.val = function(dd, dv){
		if (arguments.length) {
			self.select(dd, dv);
		} else {
			if (s && s.pop && s.length && s[0]) {
				return cfg.multiSelect? s:s[0];
			}
			return tf.val();
		}
	}
	self.txt = function(v){
		delete self.selected;
		if (arguments.length) {
			tf.val(v);
		} else {
			return tf.val();
		}
	}
	self.checkin = function(dd){
		if (dd != undefined) {
			if (!$.isArray(dd)) {
				dd = (typeof dd == 'string') ? dd.split(cfg.comma) : [ dd ];
			}
			if (!cfg.multiSelect && dd.length > 1) {
				dd = [ dd[0] ];
			}
		} else {
			dd = [];
		}
		return dd;
	}
	self.select = function(dd, tt) {
		if (cfg.allowInput && (typeof dd == 'string') && !self.data[dd]) {
			tf.val(dd);
			return;
		}
		dd = self.checkin(dd);
		if (tt != undefined) {
			self.selected = dd;
			tf.val(tt);
			return;
		}
		var dv = [], sd = [], sk = [], kf = cfg.keyField
			, df = cfg.displayField, kd = (kf && df);
		if (cfg.boxEl) {
			$.each(dd, function(n, d) {
				sk.push(kf ? d[kf] : d[n])
				dv.push(kd ? d[df] : d[n]);
				sd.push(d);
			});
		} else {
			dd = $.map(dd, function(c) {
				return '' + c;
			});
			bd.find('.tr').each(function(n, c) {
				var a = $(c), k = a.attr('name')
					, d = self.data[k], sc = 'selected';
				a.removeClass(sc).show();
				if (dd.length > 0) {
					if ($.inArray(k, dd) > -1) {
						dv.push(kd ? d[df] : d);
						sk.push(k);
						sd.push(d);
						a.addClass(sc);
					}
				}
			});
		}
		self.selected = sk;
		dv = self.displayValue = dv.join(cfg.comma);
		tf.val(dv);
		if (cfg.onSelect) {
			cfg.onSelect(self, sk, sd);
		}
//		if (!cfg.multiSelect && ) {
//			self.close();
//		}
		return self;
	}
	self.loadData = function(dd) {
		if (cfg.boxEl) {
			cfg.boxEl.loadData(dd);
			return;
		}
		bd.empty();
		if (!dd || !dd.length)
			return;
		var kf = cfg.keyField, df = cfg.displayField, kd = (kf && df);
		self.data = (kd ? {}:[]);
		var mc = cols && cols.length;
		$.each(dd, function(i, r) {
			var k = kd ? r[kf] : i;
			var a = $('<div name="' + k + '" class="tr"></div>');
			self.data[k] = r;
			if (kf && mc) {
				$.each(cols, function(n, c) {
					if (c.hidden)
						return;
					var b = $('<div class="td"></div>');
					b.width(c.width);
					b.append(c.render ? c.render(r, a, self) : r[c.field]);
					a.append(b);
				});
			} else {
				var b = $('<div class="td"></div>');
				b.append(kd? r[df] : r).width('100%');
				a.append(b);
			}
			var hc = 'hover';
			a.click(function() {
				var sl = self.selected || [];
				var i = $.inArray(k, sl), b = i > -1;
				if (cfg.multiSelect) {
					b ? sl.splice(i, 1) : sl.push(k);
					self.select(sl);
					return false;
				} else {
					self.select([k]);
					self.close();
				}
			}).hover(function() {
				bd.children('.tr').removeClass(hc);
				$(this).addClass(hc);
			}, function() {
				$(this).removeClass(hc);
			});
			bd.append(a);
		});
		if (cfg.onLoad) {
			cfg.onLoad(self, dd);
		}
	}
	var ldr = cfg.loader;
	if (cfg.data) {
		self.loadData(cfg.data);
	} else if (ldr && ldr.url) {
		$.post(ldr.url, ldr.params, function(data) {
			var ro = mac.eval(data);
			if (ro.success) {
				ro = ro.data;
				self.loadData(ro.list);
			}
		});
	}
	return self;
}